package com.ct.util;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

public class HMac {

    private static final int DEFAULT_ENCRYPTION_STRENGTH = 1;
    private static final String ENCODING_FOR_ENCRYPTION = "UTF-8";
    private String algorithm;
    private Mac mac;

    /**
     * Initializes the ShaPasswordEncoder for SHA-1 strength
     */
    public HMac() {
        this(DEFAULT_ENCRYPTION_STRENGTH);
    }

    public HMac(int strength) {
        this("HmacSHA" + String.valueOf(strength));
    }

    public HMac(String algorithm) {
        this.algorithm = algorithm;
        this.mac = getMac();
    }

    protected final Mac getMac() throws IllegalArgumentException {
        try {
            return Mac.getInstance(algorithm);
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalArgumentException("No such algorithm [" + algorithm + "]");
        }
    }

    public String encode(CharSequence password, String salt) {
        byte[] data = null;
        try {
            byte[] keys = password.toString().getBytes(ENCODING_FOR_ENCRYPTION);
            SecretKeySpec secret = new SecretKeySpec(keys, this.algorithm);
            mac.init(secret);
            byte[] bytes = salt.getBytes();
            data = mac.doFinal(bytes);
            return new String(Base64.getEncoder().encode(data), ENCODING_FOR_ENCRYPTION);
        } catch (InvalidKeyException ike) {
            throw new RuntimeException("Invalid Key while encrypting.", ike);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("Unsupported Encoding while encrypting.", e);
        }
    }

}
